#pragma once
#include<sys/epoll.h>
#include<unistd.h>
#include"Comman.hpp"
#include"Log.hpp"
//基类
class Multiplex
{
public:
    virtual bool AddEvent(int fd,uint32_t event) = 0;//添加事件
    virtual int Wait(struct epoll_event arry[],int num,int timeout) = 0;
    virtual bool ModifyEvent(int fd,uint32_t event) = 0;
    virtual bool ModyHelper(int fd,uint32_t event,int oper) = 0;
    virtual bool RemoveEvent(int fd) = 0;
};
class Epoller:public Multiplex
{    
public:
    Epoller()
    {
        _epfd = epoll_create(1);
        if(_epfd < 0)
        {
            LOG(FATAL,"epoll_create error");
            exit(CREATEPOLLSEERO);
        }
        LOG(INFO,"epoll_create success:%d\n",_epfd);
    }
    std::string ToString(uint32_t event)
    {
        std::string ret;
        if(event & EPOLLIN)
        {
            ret = "EPOLLIN";
        }
        if(event & EPOLLOUT)
        {
            ret += "| EPOLLOUT";
        }
        if(event & EPOLLET)
        {
            ret += "| EPOLLET";
        }        
        return ret;
    }
    bool ModyHelper(int fd,uint32_t event,int oper)
    {
        struct epoll_event ev;
        ev.events =  event;
        ev.data.fd = fd;
        if(epoll_ctl(_epfd,oper,fd,&ev) < 0)
        {
            LOG(FATAL,"epoll_ctl error->fd:%d,event:%s",fd,ToString(event).c_str());
            return false;
        }
        LOG(INFO,"epoll_ctl success->fd:%d,event:%s",fd,ToString(event).c_str());
        return true;
    }
    bool AddEvent(int fd,uint32_t event) override
    {
        return ModyHelper(fd,event,EPOLL_CTL_ADD);
    }
    bool ModifyEvent(int fd,uint32_t event) override
    {
        return ModyHelper(fd,event,EPOLL_CTL_MOD);
    }
    bool RemoveEvent(int fd)
    {
        return ModyHelper(fd,0,EPOLL_CTL_DEL);
    }
    int Wait(struct epoll_event arry[],int num,int timeout) override
    {
        return ::epoll_wait(_epfd,arry,num,timeout);
    }
    
    ~Epoller()
    {
    }
private:
    int _epfd;
};